package com.aaa.sso.config;

import com.aaa.sso.service.UserService;
import com.aaa.util.JwtUtil;
import com.aaa.vo.Result;
import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.web.util.WebUtils;

import java.io.PrintWriter;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;


@Configuration
public class MySecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserService userService;

    @Autowired
    private StringRedisTemplate redisTemplate;
    @Bean
    public PasswordEncoder passwordEncoder() {
        //加盐加密: 原密码+盐===>哈希加密===>密文
        //   原密码===>哈希加密===>密文 [存储大量常见的密文]
        //123456+随机产生盐===>密文
        return new BCryptPasswordEncoder();
    }


    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userService).passwordEncoder(passwordEncoder());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.formLogin()
                .successHandler(successHandler())
                .failureHandler(failureHandler())
                .loginProcessingUrl("/login").permitAll();

        http.cors();
        http.csrf().disable();
        http.authorizeRequests().anyRequest().authenticated();

    }

    private AuthenticationSuccessHandler successHandler() {
        return (request, response, authentication) -> {
            response.setContentType("application/json;charset=utf-8");
            PrintWriter writer = response.getWriter();
            //获取账号和权限
            User principal = (User)authentication.getPrincipal();
            String username = principal.getUsername();

            Collection<String> authorities = authentication.getAuthorities().stream().map(item->item.getAuthority()).collect(Collectors.toList());
            //根据账号和权限生产token;
            Map<String,Object> map=new HashMap<>();
            map.put("username",username);
            map.put("authorities",authorities);
            String token = JwtUtil.createJWT(map);

            //存入redis中。
            redisTemplate.opsForValue().set(token,"",30, TimeUnit.MINUTES);

            Result<String> result=new Result<>(2000,"登录成功",token);
            String jsonString = JSON.toJSONString(result);

            writer.print(jsonString);
            writer.flush();
            writer.close();
        };
    }

    private AuthenticationFailureHandler failureHandler() {
        return (request, response, e) -> {
            response.setContentType("application/json;charset=utf-8");
            PrintWriter writer = response.getWriter();

            Result<String> result=new Result<>(5000,"登录失败");
            String jsonString = JSON.toJSONString(result);

            writer.print(jsonString);
            writer.flush();
            writer.close();
        };
    }

    public static void main(String[] args) {
        Map<String, Object> tokenChaim = JwtUtil.getTokenChaim("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2Nzc2NjI3MDAsImlhdCI6MTY3NzU3NjMzNCwidXNlcmluZm8iOnsiYXV0aG9yaXRpZXMiOltdLCJ1c2VybmFtZSI6ImFkbWluIn19.baZKLSTyuK8vVWVBRWr__6JiiM-3u7g13V0D2MF29_E");
        System.out.println("tokenChaim = " +tokenChaim);
    }
}
